package com.zhoug.demo.audiorecorder;

import android.content.Context;

import androidx.annotation.NonNull;

import com.zhoug.audiorecorder.WavHeadUtil;
import com.zhoug.common.utils.LogUtils;
import com.zhoug.silerovad.SileroVAD;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @description: 类的简要描述
 * @author: 35574
 * @date: 2025/10/27 15:57
 */
public class VADSaveWAVFile implements ISaveWAVFile {
    private static final String TAG = ">>>SaveWAV";
    private Context context;
    private Listener listener;
    private DataOutputStream mDataOutputStream;
    private long currentRecordingStartTime;//当前文件录音开始时间
    private String mRecordingPath;//录音文件保存地址
    private long totalAudioLen;
    private SileroVAD mSileroVAD;
    private long lastMuteTime = 0;
    private final AtomicBoolean mSpeeking = new AtomicBoolean(false);

    private int sampleRate=16000;
    /**
     * VAD阈值
     */
    private float vadThreshold = 0.5f;
    /**
     * 超过时间没有说话停止保存录音文件
     */
    private long stopRecordOnMuteTime = 2000;


    public VADSaveWAVFile(Context context) {
        this.context = context;
        initVAD();
    }

    @Override
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    /**
     * VAD阈值
     * @param vadThreshold 默认 0.5f
     */
    public void setVadThreshold(float vadThreshold) {
        this.vadThreshold = vadThreshold;
    }

    /**
     * 超过时间没有说话停止保存录音文件
     * @param stopRecordOnMuteTime
     */
    public void setStopRecordOnMuteTime(long stopRecordOnMuteTime) {
        this.stopRecordOnMuteTime = stopRecordOnMuteTime;
    }

    public void setSampleRate(int sampleRate) {
        this.sampleRate = sampleRate;
    }

    private void initVAD() {
        mSileroVAD = new SileroVAD();
        mSileroVAD.loadModel(context);
    }

    @Override
    public void onAudioDataAvailable(@NonNull byte[] bytes) {
        try {
            boolean lastSpeek = mSpeeking.get();
//            byte[] audioByte = new byte[bytes.length];
//            System.arraycopy(bytes, 0, audioByte, 0, bytes.length);
            float predict = mSileroVAD.predict(bytes);
            LogUtils.d(TAG, "onAudioDataAvailable: predict=" + predict);
            boolean currentSpeek = predict >= vadThreshold;
            if (currentSpeek) {
                if (!mSpeeking.get()) {
                    mSpeeking.set(true);
                }
                //说话时重置时间
                lastMuteTime = 0;
            } else {
                if (lastMuteTime == 0) {
                    lastMuteTime = System.currentTimeMillis();
                } else {
                    //超过2秒没有说话标记为false
                    if (System.currentTimeMillis() - lastMuteTime > stopRecordOnMuteTime) {
                        mSpeeking.set(false);
                        lastMuteTime = 0;
                    }
                }
            }
            if (lastSpeek != mSpeeking.get()) {
                LogUtils.d(TAG, "onAudioDataAvailable: 说话状态改变=" + mSpeeking.get()+",predict="+predict);
            }
            if (mSpeeking.get()) {
                if (mDataOutputStream == null) {
                    currentRecordingStartTime=System.currentTimeMillis();
                    mRecordingPath = listener.getOutputFilePath();
                    LogUtils.d(TAG, "当前录音文件: " + mRecordingPath);
                    mDataOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(mRecordingPath)));
                    byte[] header = WavHeadUtil.generateWavHeader(0x7FFFFFFFL, sampleRate, 1, 16);
                    mDataOutputStream.write(header); // 先写入一个空的文件头
                    totalAudioLen = 0;
                }
                mDataOutputStream.write(bytes);
                totalAudioLen += bytes.length;
            } else {
                lastMuteTime = 0;
                stopWriteFile();
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "onAudioDataAvailable: " + e.getMessage());
        }

    }

    /**
     * 停止保存录音
     */
    @Override
    public void stopWriteFile() {
        try {
            if (mDataOutputStream != null) {
                long stopTime = System.currentTimeMillis();
                mDataOutputStream.flush();
                mDataOutputStream.close();
                mDataOutputStream = null;
                if (mRecordingPath != null) {
                    // 重新打开文件，写入正确的文件头
                    RandomAccessFile raf = new RandomAccessFile(mRecordingPath, "rw");
                    LogUtils.d(TAG, "stopWriteLastFile: totalAudioLen=" + totalAudioLen);
                    WavHeadUtil.updateWavHeader(raf, totalAudioLen);
                    raf.close();
                    listener.onSaveFileFinish(mRecordingPath,currentRecordingStartTime,stopTime);
                }
            }
        } catch (IOException e) {
            LogUtils.e(TAG, "stopWriteLastFile: " + e.getMessage());
        }
    }


    @Override
    public void release() {
        stopWriteFile();
        if(mSileroVAD!=null){
            mSileroVAD.release();
        }
    }


}
